/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

/********************************************************
 * Copyright (c) 2009, 2010 Mutsuo Saito, Makoto Matsumoto and Hiroshima
 * University.
 * Copyright (c) 2011, 2012 Mutsuo Saito, Makoto Matsumoto, Hiroshima
 * University and University of Tokyo.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of the Hiroshima University, The Uinversity
 *       of Tokyo nor the names of its contributors may be used to
 *       endorse or promote products derived from this software without
 *       specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *******************************************************/

/*
 * These numbers have been obtained from the following file :
 * https://github.com/MersenneTwister-Lab/MTGP/blob/master/cuda-sample/mtgp32dc-param-11213.c
 */

#pragma once

#include <af/defines.h>

namespace common
{
    const dim_t MaxBlocks = 32;
    const dim_t TableLength = 16*MaxBlocks;
    const dim_t MersenneN = 351;
    const dim_t MtStateLength = MaxBlocks * MersenneN;

    static unsigned pos[] = {
    88, 84, 25, 42, 22, 11, 76, 11, 42, 60, 45, 80, 81, 16, 63, 38,
    3, 55, 9, 75, 70, 63, 32, 70, 58, 33, 18, 9, 14, 91, 90, 86,
    };

    static unsigned sh1[] = {
    19, 15, 4, 20, 1, 16, 16, 15, 6, 6, 12, 6, 8, 1, 14, 28,
    30, 1, 9, 17, 15, 15, 7, 12, 21, 7, 7, 12, 16, 4, 10, 6,
    };

    static unsigned sh2[] = {
    5, 12, 18, 9, 5, 1, 6, 16, 11, 11, 13, 9, 18, 19, 18, 1,
    2, 16, 15, 6, 6, 17, 15, 10, 2, 10, 13, 13, 3, 2, 14, 7,
    };

    static unsigned mask = 4294443008;
    //static const unsigned mask[] = {
    //4294443008, 4294443008, 4294443008, 4294443008, 4294443008, 4294443008, 4294443008, 4294443008,
    //4294443008, 4294443008, 4294443008, 4294443008, 4294443008, 4294443008, 4294443008, 4294443008,
    //4294443008, 4294443008, 4294443008, 4294443008, 4294443008, 4294443008, 4294443008, 4294443008,
    //4294443008, 4294443008, 4294443008, 4294443008, 4294443008, 4294443008, 4294443008, 4294443008,
    //};

    static unsigned recursion_tbl[] = {
    0, 2879706668, 3137826695, 279165355, 570425344, 2309281324, 2567401351, 849590699,
    38330, 2879669142, 3137862205, 279129105, 570463674, 2309243798, 2567436861, 849554449,
    0, 2593609479, 1975655185, 4015344662, 357564441, 2412205854, 1620187912, 4194651151,
    53865, 2593621358, 1975699832, 4015365759, 357618288, 2412217719, 1620232545, 4194672230,
    0, 1350351572, 3879866427, 3074337519, 1908408359, 566016755, 2525106204, 3338578632,
    56684, 1350330296, 3879914839, 3074324355, 1908464971, 565995423, 2525154672, 3338565540,
    0, 1055977248, 2682116586, 2704094922, 271581238, 784396054, 2414729692, 2971481852,
    23789, 1055962061, 2682094855, 2704108071, 271604955, 784380923, 2414708017, 2971494929,
    0, 2953117369, 62376084, 3014866477, 122683469, 3075800820, 82299097, 3034789472,
    18916, 2953099101, 62357872, 3014885321, 122702249, 3075782416, 82280765, 3034808196,
    0, 1684682268, 3815655459, 2265218623, 723517535, 1330263619, 3360573564, 2888072800,
    51884, 1684733104, 3815670415, 2265232531, 723569395, 1330314479, 3360588496, 2888086732,
    0, 465136444, 2086871972, 1742358680, 574619745, 972647261, 1579361221, 1167739129,
    19553, 465119069, 2086891461, 1742341369, 574639104, 972629820, 1579380644, 1167721624,
    0, 2761653723, 3161842783, 418290052, 1969225846, 3522919853, 3373655081, 1838062066,
    50425, 2761668898, 3161792678, 418274685, 1969276047, 3522935124, 3373605072, 1838046475,
    0, 823868564, 2715863359, 2432431531, 1012924546, 226180118, 2642463165, 2895901993,
    46626, 823888566, 2715844381, 2432385929, 1012971168, 226200116, 2642444191, 2895856395,
    0, 3163477696, 1302313789, 4044451325, 2389704861, 855561821, 3287268256, 2137091424,
    40970, 3163453130, 1302272823, 4044475895, 2389745815, 855537239, 3287227306, 2137116010,
    0, 112997176, 3723016697, 3679750849, 4213178533, 4254872477, 650688860, 544508516,
    42220, 113022932, 3722976533, 3679727149, 4213220425, 4254898033, 650649008, 544485000,
    0, 612320333, 3070909104, 2473926397, 3292528821, 3762242808, 1934252549, 1463098952,
    21839, 612307202, 3070889983, 2473937842, 3292550650, 3762229687, 1934233418, 1463110407,
    0, 3452614784, 3739161126, 320187046, 3513778374, 481998918, 263131872, 3261442656,
    46663, 3452571335, 3739198561, 320150753, 3513824897, 481955329, 263169191, 3261406247,
    0, 588293362, 2445856652, 3000527742, 2311061713, 2865800227, 403230557, 991456175,
    62105, 588273259, 2445819157, 3000539623, 2311123528, 2865780410, 403193284, 991467830,
    0, 2177339548, 3971246860, 1836317584, 4080009455, 1928826995, 528772067, 2655255423,
    59650, 2177333662, 3971252750, 1836257938, 4080069101, 1928821105, 528777953, 2655195773,
    0, 3849091899, 1973261595, 2431774240, 442499322, 4279008193, 1878889953, 2324819674,
    17524, 3849076559, 1973277039, 2431756884, 442516622, 4278992821, 1878905237, 2324802222,
    0, 2208474059, 1390454348, 3510764935, 2555379979, 468886208, 3400574791, 1225917580,
    43685, 2208434542, 1390415081, 3510808354, 2555423662, 468846693, 3400535522, 1225961001,
    0, 753114312, 1662184071, 1341224527, 2666529043, 2987630043, 4259507092, 3506534236,
    32220, 753131796, 1662162779, 1341197203, 2666560719, 2987646983, 4259485256, 3506506368,
    0, 578983141, 3246792315, 3808725662, 1649410346, 1087542735, 2748718929, 2169801652,
    22528, 578997477, 3246802555, 3808744094, 1649432874, 1087557071, 2748729169, 2169820084,
    0, 2174674396, 1341825145, 3462677925, 3861905719, 1739515115, 2848629070, 676611218,
    35444, 2174644136, 1341794829, 3462713297, 3861941059, 1739484831, 2848598842, 676646630,
    0, 3312287941, 1270375145, 2396381740, 2464153923, 1468891526, 3646448554, 473293679,
    38325, 3312260464, 1270413148, 2396354457, 2464191734, 1468863539, 3646486047, 473265882,
    0, 1011438676, 4087471600, 3488123300, 455082329, 661214477, 3900824745, 3569912061,
    52539, 1011456367, 4087419083, 3488105631, 455134306, 661231670, 3900772754, 3569894854,
    0, 3529350863, 2972224887, 1668617144, 3278897504, 288202671, 1918405655, 2684687064,
    37845, 3529313562, 2972196514, 1668644973, 3278934709, 288164986, 1918377922, 2684715277,
    0, 1851876274, 2748239338, 3450842712, 3060793725, 3625018063, 364825751, 2078256933,
    54612, 1851897574, 2748192958, 3450829580, 3060847657, 3625039771, 364779971, 2078243441,
    0, 2798128189, 889378840, 2479543333, 3664773513, 2092436916, 4017281425, 1236981164,
    52108, 2798176177, 889328532, 2479497129, 3664824837, 2092484152, 4017230365, 1236934176,
    0, 1067241239, 3453461153, 4065029558, 4190110101, 3327970946, 873964340, 193686563,
    27698, 1067229989, 3453472403, 4065001860, 4190137767, 3327959728, 873975558, 193658897,
    0, 2213869621, 887682042, 3072068559, 4061135267, 1910831510, 3338203737, 1158417004,
    40265, 2213832060, 887647923, 3072104070, 4061175018, 1910793439, 3338170128, 1158453029,
    0, 3310321543, 1761913168, 2890651351, 2243953084, 1083145787, 3972311276, 697030507,
    31607, 3310290160, 1761923623, 2890640800, 2243984075, 1083114828, 3972322203, 697019420,
    0, 2168967706, 1652210191, 3812452373, 663749057, 2799162331, 1173011406, 3299699156,
    62673, 2168923851, 1652182750, 3812465860, 663811344, 2799118090, 1172983583, 3299712261,
    0, 2787116654, 1233955067, 4021071509, 3287286227, 1708132285, 2323425576, 744271686,
    37500, 2787152914, 1233926791, 4021042409, 3287323567, 1708168641, 2323397460, 744242490,
    0, 3709953686, 1938447361, 2930457239, 1075839468, 2634114938, 866803181, 4002102139,
    50633, 3709969247, 1938463176, 2930507614, 1075889189, 2634130099, 866818084, 4002152114,
    0, 1104625460, 154195956, 1223157952, 1706033657, 610746061, 1820382733, 760736057,
    35538, 1104655846, 154164518, 1223123474, 1706068779, 610776095, 1820351711, 760701931,
    };

    static unsigned temper_tbl[] = {
    0, 101711872, 634912768, 600309760, 673972224, 775684096, 234094592, 199491584,
    855825920, 890428928, 383442432, 281730560, 456056320, 490659328, 1056366080, 954654208,
    0, 6581248, 135327744, 141859840, 922910720, 929491968, 1058172928, 1064705024,
    5266944, 3420672, 138456576, 136626688, 928177664, 926331392, 1061301760, 1059471872,
    0, 69272064, 134479872, 203751936, 289406976, 358679040, 423886848, 493158912,
    544153088, 609098752, 678108672, 743054336, 825171456, 890117120, 959127040, 1024072704,
    0, 608635904, 2523648, 610373120, 5439488, 605293568, 7700992, 607292928,
    274488832, 874205696, 276487168, 876466176, 269442560, 877154816, 271178752, 879677440,
    0, 1214875648, 67174400, 1281918976, 1614020608, 677218304, 1681195008, 744261632,
    537288192, 1752159744, 604462592, 1819203072, 1077042688, 140236288, 1144217088, 207279616,
    0, 3567010304, 194572288, 3741626880, 604008960, 4036767744, 798523904, 4211392512,
    1563500032, 2309839872, 1453977088, 2184555520, 2033282048, 2913807872, 1923718144, 2788548096,
    0, 136677376, 272809984, 409421824, 2109440, 134592512, 274919424, 407336960,
    1891638784, 2028312064, 1619189248, 1755796992, 1893740032, 2026219008, 1621290496, 1753703936,
    0, 4026617856, 172764160, 4199382016, 75673600, 4102283264, 248421376, 4275031040,
    1158700544, 3037793792, 1331458560, 3210551808, 1100148224, 2979249664, 1272889856, 3151991296,
    0, 2147483648, 0, 2147483648, 3221225472, 1073741824, 3221225472, 1073741824,
    536878592, 2684362240, 536878592, 2684362240, 3758104064, 1610620416, 3758104064, 1610620416,
    0, 3225420800, 2228224, 3227649024, 809369600, 4034790400, 807141376, 4032562176,
    1073880576, 2151815680, 1075846656, 2153781760, 1882988032, 2960923136, 1881021952, 2958957056,
    0, 206130176, 1107561472, 1313685504, 537462784, 742409216, 1645020160, 1849968640,
    272670208, 470405632, 1380225536, 1577967104, 810128896, 1006688768, 1917688320, 2114246144,
    0, 807406080, 275513344, 541854208, 1573888, 808979968, 276038656, 542379520,
    269098496, 539628544, 6692352, 809899008, 269621760, 540151808, 8264192, 811470848,
    0, 1612447744, 142082048, 1751384064, 7602176, 1617428480, 135004160, 1745879040,
    10493440, 1622941184, 148381184, 1757683200, 13901312, 1623727616, 145497600, 1756372480,
    0, 1275199488, 2793406464, 3934388224, 352321536, 1493303296, 3011510272, 4286709760,
    689970688, 1696734720, 2409635328, 3282181632, 1008737792, 1881284096, 2594184704, 3600948736,
    0, 150999040, 33619968, 184619008, 2103296, 153094144, 35723264, 186714112,
    805543424, 956534272, 839032320, 990023168, 807634432, 958633472, 841123328, 992122368,
    0, 3225487872, 3876324352, 659361280, 4198400000, 981436928, 489849856, 3715337728,
    545267200, 3770749952, 3347847680, 130879488, 3669925376, 452957184, 1035115008, 4260597760,
    0, 3910139904, 2496659456, 2109734912, 3687579648, 853278720, 1327235072, 2785804288,
    164634112, 3770686976, 2634030592, 1947213312, 3525058048, 990649856, 1187782144, 2950438400,
    0, 201461760, 3812622336, 4014084096, 33554432, 235016192, 3779067904, 3980529664,
    1352670720, 1554124288, 3017809408, 3219262976, 1386225152, 1587678720, 2984254976, 3185708544,
    0, 1469123584, 3497837568, 2280507392, 2818795520, 4287783936, 2021633024, 804167680,
    5381632, 1472401920, 3492731392, 2277496320, 2823910912, 4290804224, 2016260608, 800898560,
    0, 2550235136, 537106432, 3087144960, 1074806784, 3625041920, 1611913216, 4161951744,
    212480, 2550316544, 536913408, 3087083008, 1075019264, 3625123328, 1611720192, 4161889792,
    0, 543432704, 623958016, 89454592, 27283968, 566522368, 613452288, 83143168,
    5381632, 540425728, 627230208, 84338176, 32656384, 563506176, 616731648, 78033920,
    0, 134377472, 2521945088, 2656281600, 4236288, 138597376, 2517725184, 2652045312,
    7249408, 141356544, 2520730112, 2654812672, 3029504, 137120256, 2524966400, 2659032576,
    0, 269697536, 42663936, 311968256, 1346895872, 1079722496, 1388511232, 1120944640,
    284057088, 16587776, 308633088, 41294848, 1084644864, 1354046464, 1110269440, 1379802112,
    0, 54056960, 5527552, 57442304, 22155264, 40552448, 17188864, 37654528,
    2153984, 51906048, 7636480, 55336448, 24301056, 38409728, 19305984, 35540480,
    0, 3597599744, 21800448, 3609436672, 4467200, 3593154048, 17337344, 3613886464,
    209935872, 3672922624, 231733248, 3684760576, 214397952, 3668471808, 227267072, 3689207296,
    0, 70910976, 7421952, 72041472, 272663552, 343572480, 271696896, 336314368,
    1879350784, 1950259712, 1886772736, 1951390208, 1615075840, 1685986816, 1614109184, 1678728704,
    0, 1761935360, 185210880, 1645156352, 1101029376, 681926656, 1252685824, 598702080,
    74128896, 1835933184, 258016768, 1717831168, 1170963968, 751730176, 1321297408, 667182592,
    0, 3338677248, 1516357632, 2640438272, 302069760, 3573617664, 1214312448, 2405489664,
    3368033792, 264253952, 2460079616, 1436678656, 3670091264, 499190272, 2158030336, 1201717760,
    0, 554461696, 7452672, 561893888, 3422689792, 3977146368, 3430130176, 3984574464,
    1102241280, 1623110656, 1103324672, 1624181760, 2377171968, 2898046464, 2378267648, 2899121664,
    0, 697340416, 7652864, 702829568, 1074688000, 1772020224, 1081783808, 1776952320,
    1141022208, 1838287872, 1148606464, 1843841536, 67956224, 765230080, 74983424, 770226688,
    0, 423231488, 128225280, 513708032, 6653952, 425691136, 130095104, 519772160,
    1146551808, 1567424000, 1139961344, 1523084800, 1144223232, 1560901120, 1134028288, 1521346048,
    0, 33619968, 271785984, 305274880, 268632064, 302120960, 3153920, 36773888,
    1077583360, 1111203328, 1342815744, 1376304640, 1345953280, 1379442176, 1074445824, 1108065792,
    };

}
